#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 


#include "moto.h"
#include "socketCMD.h"

#define portnumber 3333



int opt = 1;
int len = sizeof(opt);


int main(int argc, char *argv[]) 
{ 
	int socketSvr,socketConnect; 
	int socketConnect_link;	
	struct sockaddr_in server_addr; 
	struct sockaddr_in client_addr; 
	int sin_size; 
	int nbytes;
	char buffer[1024];
	char cLoopFlag = 1;
	SOCK_MSG sock_msg;
//	DIRECTION direction;
	
	if((socketSvr=socket(AF_INET,SOCK_STREAM,0))==-1)
	{ 
		fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); 
		exit(1); 
	} 

	bzero(&server_addr,sizeof(struct sockaddr_in));
	server_addr.sin_family=AF_INET;                
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);  
	server_addr.sin_port=htons(portnumber);       
	
	int val = 1;
//	setsockopt( socketSvr, SOL_SOCKET, SO_REUSEPORT, (char*)&val, sizeof(val);
	if(bind(socketSvr,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) 
	{ 
		fprintf(stderr,"Bind error:%s\n\a",strerror(errno)); 
		exit(1); 
	} 

	if(listen(socketSvr,5)==-1) 
	{ 
		fprintf(stderr,"Listen error:%s\n\a",strerror(errno)); 
		exit(1); 
	} 
	sin_size=sizeof(struct sockaddr_in); 
	socketConnect_link = -1;

	int fd = open("/dev/moto", 0);
	
	if (fd < 0) {
		fd = open("/dev/moto", 0);
	}
	if (fd < 0) {
		perror("open device moto");
		exit(1);
	}
	
	if((socketConnect = accept(socketSvr,(struct sockaddr *)(&client_addr), &sin_size)) == -1)
	{		
		fprintf(stderr,"Accept error:%s\n\a",strerror(errno)); 
		exit(1); 
	}
	printf("\n%s", "connected\n");
	
	while(cLoopFlag)
	{
		if((nbytes = read(socketConnect, &sock_msg, sizeof(SOCK_MSG))) ==-1)
 		{
			printf("nBtes: %d", nbytes);
			fprintf(stderr, "Read Error: %s\n", strerror(errno));
			setsockopt(socketSvr, SOL_SOCKET, SO_REUSEADDR, &opt, &len);
			close(socketSvr); 
			close(socketConnect); 
			
			exit(-1);
		}
		
		printf("\n\npress key is %c\n", sock_msg.command);
		
		switch(sock_msg.command)
		{
		case 's':
			{
				ioctl(fd, MOTO_IOCTL_START, 0);
				printf("\n%s", "start moto\n");
			}
			break;
		case 'S':
			{
				ioctl(fd, MOTO_IOCTL_STOP, 0);
				printf("\n%s", "stop moto\n");
			}
			break;
			
		case SOCKET_MOTOSPEED_FULL:
			{
				ioctl(fd, MOTO_IOCTL_SETSPEED, 0);
				printf("\n%s", "set full speed\n");
			}
			break;
		case SOCKET_MOTOSPEED_HALF:
			{
				ioctl(fd, MOTO_IOCTL_SETSPEED, MOTO_SPEED_HALF);
				printf("\n%s", "set half speed\n");
			}
			break;
			
		case SOCKET_MOTOSPEED_LOW:
			{
				ioctl(fd, MOTO_IOCTL_SETSPEED, MOTO_SPEED_LOW);
				printf("\n%s", "set low speed\n");
			}
			break;
			
		case SOCKET_MOTODIR_FORWARD:
			{
				ioctl(fd, MOTO_IOCTL_SETDIR, MOTO_DIR_FORWARD);
				printf("\n%s", "\nset direcory\n");
			}
			break;
			
		case SOCKET_MOTODIR_LEFT:
			{
				ioctl(fd, MOTO_IOCTL_SETDIR, MOTO_DIR_LEFT);
				printf("\n%s", "\nset direcory\n");
			}
			break;

		case SOCKET_MOTODIR_RIGHT:
			{
				ioctl(fd, MOTO_IOCTL_SETDIR, MOTO_DIR_RIGHT);
				printf("\n%s", "\nset direcory\n");
			}
			break;

		case SOCKET_DISCONNECT:
		{
			cLoopFlag = 0;
			printf("\nclose moto, exit application!\n");
		}
		break;
		
		default:
			{
				printf("\nundefined %c\n", sock_msg.command);
			}
		}		
	}
	close(fd);

	setsockopt(socketSvr, SOL_SOCKET, SO_REUSEADDR, &opt, &len);
	
	close(socketSvr); 
	close(socketConnect); 
	

	exit(0); 
} 
